package com.ouyunc.common.base;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义请求
 */
public class Request implements Serializable {
    private static final long serialVersionUID = 200;


    /**
     * 请求路径：http://localhost:8080/user/123
     */
    private String url;

    /**
     * 请求头：key ,value  格式，会封装到对应的实现类的请求头中
     */
    private Header header;

    /**
     * 请求参数，类似@requestParam拼接到url 上的
     */
    private Param param;

    /**
     * 请求体body: 对应@requestBody
     */
    private Body body;

    /**
     * 文件上传，可以多个文件上传，在文件上传的模式中不可以使用body ,也就是body 设置的参数无效
     */
    private Map<String, List<MultipartFile>> files;

    /**
     * 请求配置，可以设置超时时间连接时间等参数
     */
    private Config config;


    public String getUrl() {
        return url;
    }

    public Map<String, String> getHeader() {
        return header.headerMap;
    }
    public Config getConfig() {
        return config;
    }
    public Map<String, String> getParam() {
        return param.paramMap;
    }

    public Object getBody() {
        return body.body;
    }

    public int getReadTimeout() {
        return config.readTimeout;
    }

    public int getConnectTimeout() {
        return config.connectTimeout;
    }

    public Map<String, List<MultipartFile>> getFiles() {
        return files;
    }

    private static class Header{
        private Map<String, String> headerMap = new HashMap<>();

        public void put(String name, String value) {
            headerMap.put(name, value);
        }
        public void putAll(Map<String, String> headerMap) {
            headerMap.putAll(headerMap);
        }
    }
    private static class Param{
        private  Map<String, String> paramMap = new HashMap<>();

        public void put(String key, String value) {
            paramMap.put(key, value);
        }
        public void putAll(Map<String, String> paramMap) {
            paramMap.putAll(paramMap);
        }
    }

    private static class Body{
        private Object body;
        public void body(Object body) {
            this.body = body;
        }
    }



    private static class Config{
        // 连接超时时间
        private int connectTimeout;
        // 读超时时间
        private int readTimeout;

    }

    public static Builder newBuild() {
        return new Builder();
    }
    //进行构建
    private Request(Builder builder) {
        this.url = builder.url;
        this.header = builder.header;
        this.param = builder.param;
        this.config = builder.config;
        this.body = builder.body;
        this.files = builder.files;
    }

    public static class Builder {
        /**
         * 请求路径：http://localhost:8080/user/123
         */
        private String url;

        /**
         * 请求头：key ,value  格式，会封装到对应的实现类的请求头中
         */
        private Header header = new Header();

        /**
         * 请求参数，类似@requestParam拼接到url 上的
         */
        private Param param = new Param();


        /**
         * 请求体body: 对应@requestBody
         */
        private Body body = new Body();

        /**
         * 文件上传，可以多个文件上传，在文件上传的模式中不可以使用body ,也就是body 设置的参数无效
         */
        private Map<String, List<MultipartFile>> files = new HashMap<>();

        /**
         * 请求配置，可以设置超时时间连接时间等参数
         */
        private Config config = new Config();

        private Builder() {
        }

        public Builder url(String url) {
            this.url = url;
            return this;
        }

        public Builder headers(Map<String, String> headerMap) {
            this.header.putAll(headerMap);
            return this;
        }

        public Builder header(String name, String value) {
            this.header.put(name,value);
            return this;
        }

        public Builder param(String name, String value) {
            this.param.put(name,value);
            return this;
        }

        public Builder params(Map<String, String> paramsMap) {
            this.param.putAll(paramsMap);
            return this;
        }

        public Builder body(Object body) {
            this.body.body(body);
            return this;
        }

        public Builder files(String paramName, List<MultipartFile> files) {
            this.files.put(paramName, files);
            return this;
        }

        public Builder file(String paramName, MultipartFile file) {
            List<MultipartFile> files = this.files.get(paramName);
            if (CollectionUtils.isNotEmpty(files)) {
                files.add(file);
            }else {
                files = new ArrayList<>();
                files.add(file);
            }
            this.files.put(paramName, files);
            return this;
        }

        public Builder connectTimeout(int connectTimeout) {
            this.config.connectTimeout = connectTimeout;
            return this;
        }
        public Builder readTimeout(int readTimeout) {
            this.config.readTimeout = readTimeout;
            return this;
        }
        public Builder config(int connectTimeout, int readTimeout) {
            this.config.connectTimeout = connectTimeout;
            this.config.readTimeout = readTimeout;
            return this;
        }
        public Request build() {
            return new Request(this);
        }
    }

}
